﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.DirectoryServices.AccountManagement;

namespace ScrumFactory.Services.Web.WindowsAuth {

    public partial class Default : System.Web.UI.Page {

        private PrincipalContext adContext;

        private ScrumFactory.Services.AuthProviders.IWindowsTokenStore tokenStore = null;

           
        private string WindowsAutheticationServer {
            get {
                return System.Configuration.ConfigurationManager.AppSettings["WindowsAutheticationServer"];
            }
        }

        private string DomainName {
            get {
                try {
                    if (String.IsNullOrEmpty(WindowsAutheticationServer))
                        return System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain().Name;
                    else
                        return WindowsAutheticationServer;
                }
                catch (Exception) {
                    return String.Empty;
                }
            }
        }

        private string GetFullUserName(string user) {
            if (String.IsNullOrEmpty(user))
                return user;
            if (user.IndexOf("@") > 0)
                return user.ToLower();

            if(user.IndexOf("\\") > 0)
                user = user.Substring(user.IndexOf("\\")+1);

            return (user + "@" + DomainName).ToLower();
        }

        private void GetTokenStore() {
            tokenStore = ScrumFactory.Services.Web.Application.CompositionContainer.GetExportedValue<AuthProviders.IWindowsTokenStore>();
        }

        private string WindowsUser {
            get {
                return GetFullUserName(Request.ServerVariables["LOGON_USER"]);
            }
        }

        protected void Page_Load(object sender, EventArgs e) {

            try {
                GetADContext();

                domainLiteral.Text = DomainName;
                widowsUserLiteral.Text = WindowsUser;


            }
            catch (Exception ex) {
                SetMessage(ex.Message);
                windowsAuthPanel.Visible = false;
                loginPanel.Visible = false;
                return;
            }
            
            if (!IsPostBack)
                SetDefaultPanelsVisibility();

        }

        private void SetDefaultPanelsVisibility() {
            if (!String.IsNullOrEmpty(WindowsUser)) {
                windowsAuthPanel.Visible = true;
                loginPanel.Visible = false;
            }
            else {
                windowsAuthPanel.Visible = false;
                loginPanel.Visible = true;
            }
        }

        protected void Show_LoginPanel_Click(object sender, EventArgs e) {

            loginPanel.Visible = true;
            windowsAuthPanel.Visible = false;

        }

        protected void SigninWindowsUser_Click(object sender, EventArgs e) {
            GetTokenStore();
            string token = tokenStore.CreateTokenFor(WindowsUser);
            SuccessRedirect(token);
        }

        protected void Signin_Click(object sender, EventArgs e) {

            string user = GetFullUserName(userTextBox.Text);

            SetMessage("");

            if (!UserValidated(user, passwordTextBox.Text))
                return;

            GetTokenStore();

            string token = tokenStore.CreateTokenFor(user);

            SuccessRedirect(token);

        }

        private void GetADContext() {            
            if (String.IsNullOrEmpty(WindowsAutheticationServer))
                adContext = new PrincipalContext(ContextType.Domain);
            else
                adContext = new PrincipalContext(ContextType.Domain, WindowsAutheticationServer);            
        }
        
        private bool UserValidated(string user, string password) {

            try {
                using (adContext) {
                    if (adContext.ValidateCredentials(user, password))
                        return true;
                    else
                        SetMessage("Incorrect user or password.");
                }
            }
            catch (Exception ex) {
                SetMessage("Error validating user at domain.<br/>" + ex.Message);
            }
            
            return false;            
        }

        private void SetMessage(string message) {
            messageLiteral.Text = message;
        }

        private void SuccessRedirect(string token) {
            Response.Redirect("AuthOk.aspx?code=" + token);
        }
    }
}